package maUtil;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;

public class LogFile {
	String _sFileName = "log.txt";
	File _file = null;
	FileOutputStream _fos;
	
	private static String _sFolderName = null;
	private static String _sDirPath = null;
	private static String _sDesPath = null;
	
	public LogFile()
	{
		_file = new File(_sDirPath + _sFileName);
	}
	public LogFile(String str)
	{
		if(str == null) return;
		_sFileName = str;
		_file = new File(_sDirPath + _sFileName);
		try {
			_fos = new FileOutputStream(_file);
		} catch (FileNotFoundException e) {
			System.out.println("Failed to open log file. " + e.getMessage());
		}
	}
	/**
	 * log string as a paragraph by adding two empty lines after it
	 * NOTE: empty line in csv file will cause problem in D3 reporting 
	 * -- please don't use this method when writing to csv files.
	 * */
	public void log(String str)
	{
		logPln(str);
		logPln("\r\n\r\n");
	}
	/**
	 * log string and add the start of a new line
	 * 
	 * */
	public void logLn(String str)
	{
		logPln(str);
		logPln("\r\n");
	}
	
	/**
	 * log plain string without add anything
	 * 
	 * */
	public void logPln(String str)
	{
		try {
			_fos.write(str.getBytes());
		} catch (IOException e) {
			System.out.println("*****************************Failed to write log file.***************************");
		}
	}
	
	public void close()
	{
		try {
			_fos.close();
		} catch (IOException e) {
			System.out.println("Failed to close FileOutputStream " + _file.getAbsoluteFile());
			e.printStackTrace();
		}
	}
	
	protected void finalize()
	{
		close();
	}
	
	public static String getFolderName()
	{
		return _sFolderName;
	}
	
	public static void setFolderName(String str)
	{
		_sFolderName = str;
	}
	
	public static String getPath()
	{
		return _sDirPath;
	}
	
	public static void setPath(String path)
	{//if folder name is not end with '\' then add '\'
		if(path == null) return;
		int n = path.length()-1;
		if(path.charAt(n) != '\\')
			path += '\\';
		_sDirPath = path;
	}
	
	public static void setDesPath(String str)
	{
		_sDesPath = str;
	}
	
	public static String getDesPath()
	{
		return _sDesPath;
	}
	
	public static void compareHistoricalData()
	{
		SortedRecordsF sr = findLatestLogFolder();
		if(sr.getSize() > 0)
		{//have got folders above
			SortedRecordsF srOutput = new SortedRecordsF(100, "");
			LogFile log = new LogFile("History.csv");
			ArrayList<RecordUnitF> rl = sr.getAll();
			Iterator<RecordUnitF> it = rl.iterator();
			RecordUnitF ru = null;
			while(it.hasNext())
			{//for each folder read the "SumProjects.csv" file
				ru = (RecordUnitF) it.next();
				//String str1 = ".\\log\\" + ru.getValue() + "\\" + "SumProjects.csv";
				File file = new File(ru.getStr() + "\\SumProjects.csv");
				String ret = findInCSVFile(file, "\"TOTAL\"");
				if(ret != null)
				{
					RecordUnitF unit = new RecordUnitF( Float.valueOf(ret.trim()).floatValue(), ((long)ru.getValue()) + "");
					srOutput.addWithoutSort(unit);
				}
			}
			log.logLn("Value,Time");
			log.logPln(srOutput.getAllStringCSV());
		}
	}
	
	
	public static SortedRecordsF findLatestLogFolder()
	{
		SortedRecordsF sr = null;
		File logFolder = new File(_sDirPath);
		logFolder = logFolder.getParentFile();
		File[] folderList = logFolder.listFiles();
		if(folderList != null)
		{//is folder is not empty
			sr = new SortedRecordsF(52, "");//52 = number of weeks in one year
			for(int i = 0; i < folderList.length; i++)
			{//loop for each folder
				if(folderList[i].isDirectory())
				{//for all folders under log, find the six latest folder 
					String name = folderList[i].getName();
					//Float n = Float.valueOf(name.trim()).floatValue(); //Integer.parseInt(name.substring(0, 10));
					Float n = new Float(name);
					RecordUnitF ru = new RecordUnitF(n, folderList[i].getPath());
					sr.add(ru);
				}
			}
		}
		return sr;
	}
	
	
	/* read though a CSV file and return a string under given name
	 * file: the CSV file to read
	 * recordName: the record name to search
	 * return value: the value part of the record
	 * */
	public static String findInCSVFile(File file, String recordName)
	{
		String ret = null;
		if(!file.exists())
			return ret;//skip if file does not exist
		BufferedReader bufRdr = null;
		try {
			bufRdr = new BufferedReader(new FileReader(file));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("Failed to open file: " + file.getPath());
			return ret;
		}
		String line = null;
		try {
			while((line = bufRdr.readLine()) != null)
			{
				StringTokenizer st = new StringTokenizer(line,",");
				String str[] = {"","","","",""};
				int i = 0;
				while (st.hasMoreTokens() && i < 5)
				{
					str[i] = st.nextToken();
					i++;
				}
				if(str[1].equals(recordName))
				{
					ret = str[0];
					break;
				}
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ret;
	}
	
	
	/* read though a CSV file and return a string under given name
	 * file: the CSV file to read
	 * recordName: the record name to search
	 * return value: the value part of the record
	 * */
	public static HashMap<String, String> readCSVFile(File file)
	{
		HashMap<String, String> ret = new HashMap<String, String>();
		
		if(!file.exists())
			return ret;//skip if file does not exist
		BufferedReader bufRdr = null;
		try {
			bufRdr = new BufferedReader(new FileReader(file));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("Failed to open file: " + file.getPath());
			return ret;
		}
		String line = null;
		try {
			while((line = bufRdr.readLine()) != null)
			{
				StringTokenizer st = new StringTokenizer(line,",");
				String strList[] = {"","","","",""};
				int i = 0;
				while (st.hasMoreTokens() && i < 5)
				{
					strList[i] = st.nextToken();
					i++;
				}
				if(strList.length >= 2)
				{//HashMap<Key, Value>
					if(strList[0].equals("ClassName"))
					{//skip the title
						continue;
					}
					ret.put(strList[0], strList[1]);
				}
				//ret.add(strList);
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		return ret;
	}
	
	//copy all the content in one directory to another
	public static void copyDirectory(File sourceLocation , File targetLocation) throws IOException 
	{
		if (sourceLocation.isDirectory()) 
		{
            if (!targetLocation.exists()) 
            {
                targetLocation.mkdir();
            }

            String[] children = sourceLocation.list();
            for (int i=0; i<children.length; i++) 
            {
                copyDirectory(new File(sourceLocation, children[i]),
                        new File(targetLocation, children[i]));
            }
        } 
		else 
		{
            InputStream in = new FileInputStream(sourceLocation);
            OutputStream out = new FileOutputStream(targetLocation);
            // Copy the bits from instream to outstream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }
	}
	//delete a file or a folder with all its subfolders and files inside
	public static void delete(File f) throws IOException 
	{
		if (f.isDirectory()) 
		{
		    for (File c : f.listFiles())
		      delete(c);
		}
		if (!f.delete())
		    throw new FileNotFoundException("Failed to delete file: " + f);
	}

}
